package com.whirl.controller;

import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.whirl.entity.Forecast;
import com.whirl.entity.Weather;
import com.whirl.mapper.WeatherMapper;
import com.whirl.service.WeatherService;
import com.whirl.util.NumUtils;
import ml.dmlc.xgboost4j.java.Booster;
import ml.dmlc.xgboost4j.java.DMatrix;
import ml.dmlc.xgboost4j.java.XGBoost;
import ml.dmlc.xgboost4j.java.XGBoostError;
import org.springframework.context.annotation.Bean;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;


import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.whirl.util.Constants.MLData_PATH;

/**
 * @author xw
 * @date 2022/8/12 13:07
 */

@RestController
public class ForecastController {

    @Resource
    WeatherService weatherService;

    /**
     * 查询数据库的天气信息
     */
    @GetMapping("/getWeather")
    public List<Weather> getWeather() {
        return weatherService.getWeather();
    }

    /**
     * 预测负载率并输出结果到控制台
     */
    @RequestMapping("/predict")
    public void predict() throws XGBoostError {
        long startTime = System.currentTimeMillis();

        // 写入文件位置
        String filePath = "src/main/java/com/whirl/ai_ml/ai_predict.txt";
        // 调用天气接口，获取特征参数并整理好为libsvm格式写入文件filePath
        getForecastAndSetWeatherInFile(filePath);

        // 加载训练好的模型
        Booster booster = XGBoost.loadModel("model/xgb_model.model");
        // 调整为XGBoost需要的DMatrix格式
        DMatrix temper_humidity_mat = new DMatrix(filePath);

        // 预测结果
        System.out.print("预测值： ");
        float[][] predicts = booster.predict(temper_humidity_mat);
        for (int i = 0; i < predicts.length; i++) {
            for (int j = 0; j < predicts[0].length; j++) {
                BigDecimal retain2 = NumberUtil.round(predicts[i][j], 2);
                predicts[i][j] = retain2.floatValue();
                System.out.print(predicts[i][0] + "  ");  // 写[i][j]结果也一样的，因为 predicts[0].length = 1
            }
        }

        long endTime = System.currentTimeMillis();
        System.out.println("\nspend time: " + (endTime - startTime) / 1000.0 + "s");
    }

    /**
     * 获取天气预报并存储到数据库和libsvm文件中
     */
//    @RequestMapping("/getForecastAndSetWeather")
    public void getForecastAndSetWeatherInFile(String filePath) {
        RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory()); //Apache Httpclient
        // 消息转换器列表
        List<HttpMessageConverter<?>> httpMessageConverters = restTemplate.getMessageConverters();
        httpMessageConverters.forEach(httpMessageConverter -> {
            if (httpMessageConverter instanceof StringHttpMessageConverter) {
                // 配置消息转换器StringHttpMessageConverter，并设置utf-8
                StringHttpMessageConverter messageConverter = (StringHttpMessageConverter) httpMessageConverter;
                messageConverter.setDefaultCharset(StandardCharsets.UTF_8);
            }
        });
        Map<String, String> params = new HashMap<>();
//        https://devapi.qweather.com/v7/weather/3d?location=101200101&key=3db9f5ed4a754711b83304ccd01bd1af

        params.put("location", "101250201");  // 湘潭
        params.put("key", "3db9f5ed4a754711b83304ccd01bd1af");  // 密钥

        // 查7天的，把3d换成7d即可，同样的，也可以切换为24h查看24小时的天气预报
        ResponseEntity<String> forObject = restTemplate.getForEntity("https://devapi.qweather.com/v7/weather/3d?location={location}&key={key}", String.class, params);

//        System.out.println("forObject: " + forObject);
        JSONObject jsonObject1 = JSONObject.parseObject(forObject.getBody());
        JSONArray daily = null;
        List<Forecast> forecasts = null;
        if (jsonObject1 != null) {
            daily = jsonObject1.getJSONArray("daily");
            forecasts = JSONObject.parseArray(daily.toString(), Forecast.class);
        }

        // 获取到了天气数据json，需要修改部分数据的格式，比如时间，温度，湿度
        weatherService.processWeather(forecasts, filePath);
    }
}
